home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 May: Technology Seed / Mac Tech Seed May '97.toast / QuickTime™ VR 2.0 SDK / QTVR C⁄C++ Runtime API / Sample Code / VRShell Sample Code / Common Files / Mac Framework / MacFramework.c next >
Encoding:
Text File  |  1997-02-21  |  24.5 KB  |  1,085 lines  |  [TEXT/MPCC]

  1. //
  2. //    File:        MacFramework.c
  3. //
  4. //    Contains:    Basic functions for windows, menus, and similar things.
  5. //
  6. //    Written by:    Tim Monroe
  7. //                Based (heavily!) on the MovieShell code written by Apple DTS
  8. //
  9. //    Copyright:    © 1994-1996 by Apple Computer, Inc., all rights reserved.
  10. //
  11. //    Change History (most recent first):
  12. //
  13. //       <9>         01/06/97    rtm        DoIdle now called for all open app windows
  14. //       <8>         01/02/97    rtm        added gAppInForeground flag
  15. //       <7>         12/17/96    rtm        fixed crashing bug in DoCreateMovieWindow
  16. //                                    (hitting Cancel in open dialog left wrong port setting)
  17. //       <6>         12/17/96    rtm        added GetAppDataFromFrontWindow, GetAppDataFromWindow, GetAppDataFromWindowObject
  18. //       <5>         12/09/96    rtm        added RemoveApplicationWindowObject hook to allow app-specific clean-up
  19. //       <4>         12/04/96    rtm        added support for HL events
  20. //       <3>         12/02/96    rtm        added CheckMovieControllers function
  21. //       <2>         11/27/96    rtm        conversion to personal coding style
  22. //       <1>         12/20/94    khs        first file
  23. //       
  24. //
  25.  
  26. // header files
  27. #include <SegLoad.h>
  28. #include <ToolUtils.h>
  29. #include <Devices.h>
  30. #include <Fonts.h>
  31.  
  32. #include "DTSQTUtilities.h"
  33. #include "AppConfiguration.h"
  34. #include "MacFramework.h"
  35.  
  36.  
  37. // window definitions
  38. Rect                gDefaultWinRect;
  39. Rect                gLimitRect = {0, 0, 480, 640};    // max size for any window
  40. long                gMCFlags = kMCFlags;
  41.  
  42. // global variables
  43. Boolean             gQuitFlag = false;                // flag that keeps track of termination state
  44. unsigned long        gWNEsleep = kWNEDefaultSleep;    // WaitNextEvent sleep time
  45. Str255                 gWindowTitle = "\pUntitled";    // default name for created windows
  46. GrowZoneUPP            gAppGrowZoneUPP;                // our grow zone callback
  47. Boolean                gAppInForeground;                // is our application in the foreground?    
  48.  
  49. // pure Macintosh Toolbox functions
  50.  
  51. //////////
  52. //
  53. // InitMacEnvironment
  54. // Initialize the Macintosh runtime environment.
  55. //
  56. //////////
  57.  
  58. void InitMacEnvironment (long theNumMasters)
  59. {
  60.     long        myIndex;
  61.     
  62.     // expand heap zone to its limit
  63.     MaxApplZone();
  64.     
  65.     for (myIndex = 0; myIndex < theNumMasters; myIndex++) {
  66.         MoreMasters();
  67.     }
  68.     
  69.     InitGraf(&qd.thePort);
  70.     InitFonts();
  71.     FlushEvents(everyEvent, 0);
  72.     InitWindows();
  73.     InitMenus();
  74.     TEInit();
  75.     InitCursor();
  76.     InitDialogs(NULL);
  77.     
  78.     // install a growzone proc warning about low memory situation
  79.     gAppGrowZoneUPP = NewGrowZoneProc(AppGrowZoneCallback);
  80.     SetGrowZone(gAppGrowZoneUPP);
  81.     
  82.     // initialize foreground/background state
  83.     gAppInForeground = true;
  84.     
  85.     // do any application-specific initialization
  86.     InitApplication();
  87. }
  88.  
  89.  
  90. //////////
  91. //
  92. // InitStack
  93. // Add some extra space to the stack.
  94. //
  95. //////////
  96.  
  97. void InitStack (long theExtraStackSpace)
  98. {
  99.     Ptr            mySize;
  100.     
  101.     mySize = GetApplLimit();
  102.     SetApplLimit(mySize - theExtraStackSpace);
  103. }
  104.  
  105.  
  106. //////////
  107. //
  108. // AppGrowZoneCallback
  109. // Our grow zone procedure.
  110. //
  111. //////////
  112.  
  113. pascal void AppGrowZoneCallback (void)
  114. {
  115.     long        myA5;
  116.     Size        myTempSize;
  117.     Size        myAvailMem;
  118.     
  119.     myA5 = SetCurrentA5();
  120.     
  121.     myAvailMem = MaxMem(&myTempSize);
  122.  
  123.     if (myAvailMem < kAvailableMem) {
  124.         ShowWarning("\pWe are running out of memory, increase the application heap! Exiting the application.", 0);
  125.         ExitToShell();
  126.     }
  127.     
  128.     SetA5(myA5);
  129. }
  130.  
  131.  
  132. //////////
  133. //
  134. // InitMenubar
  135. // Set up the menu bar.
  136. //
  137. //////////
  138.  
  139. Boolean InitMenubar (void)
  140. {
  141.     Handle        myMenuHandle = NULL;
  142.     
  143.     myMenuHandle = GetNewMBar(mMenubar); DebugAssert(myMenuHandle != NULL);
  144.     if (myMenuHandle == NULL) {
  145.         ShowWarning("\pCould not find the Menubar resource!", 0);
  146.         return(false);
  147.     }
  148.     
  149.     SetMenuBar(myMenuHandle);
  150.     DisposeHandle(myMenuHandle);  DebugAssert(MemError() == noErr);
  151.     
  152.     AddResMenu(GetMHandle(mApple), 'DRVR');
  153.  
  154.     DrawMenuBar();
  155.     
  156.     return(true);
  157. }
  158.  
  159.  
  160. //////////
  161. //
  162. // HandleMenuCommand
  163. // Handle a menu selection.
  164. //
  165. //////////
  166.  
  167. void HandleMenuCommand (long theMenuResult)
  168. {
  169.     short        myMenuID, myMenuItem;
  170.     Str255        myDAName;
  171.     
  172.     SetCursor(&qd.arrow);
  173.  
  174.     myMenuID = HiWord(theMenuResult);
  175.     myMenuItem = LoWord(theMenuResult);
  176.     
  177.     switch (myMenuID) {
  178.     
  179.         case mApple:
  180.             switch (myMenuItem) {
  181.                 case iAbout:    // about box
  182.                     ShowAboutDialogBox();     
  183.                     break;
  184.                 
  185.                 default:         // Apple menu handling
  186.                     GetItem(GetMHandle(mApple), myMenuItem, myDAName);
  187.                     (void)OpenDeskAcc(myDAName);
  188.                     break;
  189.             }
  190.             break;
  191.  
  192.         case mFile:
  193.             switch (myMenuItem) {
  194.                 case iNew:
  195.                     if (!DoCreateNewMovie()) {
  196.                         SysBeep(kDefaultSysBeep);
  197.                         ShowWarning("\pCould not create a new movie!", 0);
  198.                         break;
  199.                     }
  200.                     break;
  201.                     
  202.                 case iOpen:
  203.                     if (!DoCreateMovieWindow(NULL)) {
  204.                         ShowWarning("\pCould not create a new movie window!", 0);
  205.                         SysBeep(kDefaultSysBeep); 
  206.                         break;
  207.                     }
  208.                     break;
  209.                 
  210.                 case iClose:
  211.                     DoDestroyMovieWindow(FrontWindow());
  212.                     break;
  213.                 
  214.                 case iSave:
  215.                     if (!DoUpdateMovieFile(FrontWindow())) {
  216.                         SysBeep(kDefaultSysBeep);
  217.                         ShowWarning("\pCould not save the movie file!", 0);
  218.                         break;
  219.                     }
  220.                     break;
  221.                     
  222.                 case iSaveAs: {
  223.                     MovieController myMC;
  224.                     
  225.                     myMC = GetMCFromFrontWindow();
  226.                     if (myMC == NULL) {
  227.                         SysBeep(kDefaultSysBeep); 
  228.                         break;
  229.                     }
  230.                         
  231.                      if (QTUSaveMovie(MCGetMovie(myMC)) != noErr) {
  232.                          SysBeep(kDefaultSysBeep);
  233.                          ShowWarning("\pCould not save the movie file!", 0);
  234.                          break;
  235.                      }
  236.                          
  237.                     break;
  238.                 }
  239.                                     
  240.                 case iPrint: {
  241.                     MovieController        myMC;
  242.                     OSErr                myErr = noErr;
  243.  
  244.                     myMC = GetMCFromFrontWindow();
  245.                     if (myMC != NULL) {
  246.                         myErr = QTUPrintMoviePICT(MCGetMovie(myMC), kDefaultX, kDefaultY, kPrintFrame); 
  247.                         if (myErr != noErr) {
  248.                             ShowWarning("\pCould not print!", myErr);
  249.                             SysBeep(kDefaultSysBeep);
  250.                         }
  251.                     } else
  252.                         SysBeep(kDefaultSysBeep);
  253.                     break;
  254.                 }
  255.  
  256.                 case iQuit:
  257.                     gQuitFlag = true;
  258.                     
  259.                     // do any application-specific shutdown
  260.                     StopApplication();
  261.                     break;
  262.  
  263.             }
  264.             break;
  265.     
  266.         
  267.         // Provide the default controller cut, copy and paste functionality.    
  268.         case mEdit: {
  269.             Movie                myMovie = NULL;
  270.             MovieController        myMC;
  271.             
  272.             myMC = GetMCFromFrontWindow();
  273.             if (myMC == NULL)
  274.                 break;
  275.             
  276.             switch (myMenuItem) {
  277.                 case iUndo:
  278.                     MCUndo(myMC);
  279.                     break;
  280.                 
  281.                 case iCut:
  282.                     myMovie = MCCut(myMC);
  283.                     break;
  284.                 
  285.                 case iCopy:
  286.                     myMovie = MCCopy(myMC);
  287.                     break;
  288.                 
  289.                 case iPaste:
  290.                     MCPaste(myMC, NULL);
  291.                     break;
  292.                 
  293.                 case iClear:
  294.                     MCClear(myMC);
  295.                     break;
  296.                 
  297.                 case iSelectAll:  
  298.                     if (QTUSelectAllMovie(myMC) != noErr)
  299.                         SysBeep(kDefaultSysBeep);
  300.                     break;
  301.             }
  302.             
  303.             if (myMovie) {
  304.                 PutMovieOnScrap(myMovie, 0);
  305.                 DisposeMovie(myMovie);  DebugAssert(MemError() == noErr);
  306.             }
  307.             
  308.             break;
  309.         }
  310.  
  311.  
  312.     default:
  313.         HandleApplicationMenu(myMenuID, myMenuItem);
  314.         break;
  315.     }
  316.     
  317.     HiliteMenu(0);
  318. }
  319.  
  320.  
  321. //////////
  322. //
  323. // AdjustMenus
  324. // Adjust the application's menus.
  325. //
  326. //////////
  327.  
  328. void AdjustMenus (void)
  329. {
  330.     WindowRef            myWindow;
  331.     MovieController        myMC;
  332.     WindowObject        myWindowObject;
  333.  
  334.     myWindow = FrontWindow();
  335.  
  336.     if (myWindow != NULL) {
  337.         EnableItem(GetMHandle(mFile), iClose);
  338.         
  339.         if ((myWindowObject = (WindowObject)GetWRefCon(myWindow)) != NULL) {
  340.         
  341.             myMC = (**myWindowObject).fController;
  342.             if ((IsWindowObjectOurs(myWindowObject)) && (myMC != NULL)) {
  343.                 MCSetUpEditMenu(myMC, 0L, GetMHandle(mEdit));
  344.                 EnableItem(GetMHandle(mEdit), iSelectAll);
  345.                 EnableItem(GetMHandle(mFile), iSave);
  346.                 EnableItem(GetMHandle(mFile), iSaveAs);
  347.                 EnableItem(GetMHandle(mFile), iClose);
  348.                 EnableItem(GetMHandle(mFile), iPrint);
  349.             }
  350.         }
  351.     } else {
  352.         DisableItem(GetMHandle(mFile), iSave);
  353.         DisableItem(GetMHandle(mFile), iSaveAs);
  354.         DisableItem(GetMHandle(mFile), iClose);
  355.         DisableItem(GetMHandle(mFile), iPrint);
  356.         
  357.         DisableItem(GetMHandle(mEdit), iCut);
  358.         DisableItem(GetMHandle(mEdit), iCopy);
  359.         DisableItem(GetMHandle(mEdit), iPaste);
  360.         DisableItem(GetMHandle(mEdit), iUndo);
  361.         DisableItem(GetMHandle(mEdit), iClear);
  362.         DisableItem(GetMHandle(mEdit), iSelectAll);
  363.         
  364.     }
  365.     
  366.     AdjustApplicationMenus();                    // fix any app-specific menus as well
  367. }
  368.  
  369.  
  370. //////////
  371. //
  372. // CheckMovieControllers
  373. // Let all movie controllers have a chance to process the event.
  374. //
  375. //////////
  376.  
  377. Boolean CheckMovieControllers (EventRecord *theEvent)
  378. {    
  379.     WindowPtr                myWindow;
  380.     Boolean                    isMovieEvent = false;
  381.     WindowObject            myWindowObject;
  382.     MovieController            myMC;
  383.     
  384.     myWindow = FrontWindow();
  385.     while (myWindow) {    
  386.          myWindowObject = (WindowObject)GetWRefCon(myWindow);
  387.         if (myWindowObject) {
  388.             if (IsWindowObjectOurs(myWindowObject)) {
  389.                 myMC = (**myWindowObject).fController;
  390.                 if (myMC) {
  391.                     if (MCIsPlayerEvent(myMC, theEvent)) {
  392.                         isMovieEvent = true;    
  393.                     }        
  394.                 }
  395.             }
  396.         }
  397.         myWindow = (WindowPtr)(((WindowRecord*)myWindow)->nextWindow);
  398.     }
  399.     
  400.     return(isMovieEvent);
  401. }
  402.  
  403.  
  404. //////////
  405. //
  406. // MainEventLoop
  407. // Retrieve and process events.
  408. //
  409. //////////
  410.  
  411. void MainEventLoop (void)
  412. {
  413.     EventRecord                myEvent;
  414.     WindowRef                myWindow;
  415.     Boolean                    isMovieEvent;
  416.     short                    myWindowPart;
  417.     Rect                    myScreenRect;
  418.     Rect                    myRefreshArea;
  419.     Point                    myPoint  = {100, 100};
  420.     
  421.     while (!gQuitFlag) {
  422.         WaitNextEvent(everyEvent, &myEvent, gWNEsleep, NULL);
  423.         
  424. #ifdef USESIOUX
  425.         SIOUXHandleOneEvent(&myEvent);
  426. #endif USESIOUX
  427.  
  428.         AdjustMenus();
  429.             
  430.         // first, let all active movie controllers have access to the event
  431.         isMovieEvent = CheckMovieControllers(&myEvent);
  432.  
  433.         // then, if this wasn't a movie controller event, pass it on to the case statement 
  434.         // that dispatches the event to the right function.
  435.         if (!isMovieEvent) {
  436.         
  437.             myWindow = FrontWindow();
  438.     
  439.             switch (myEvent.what) {
  440.                 case mouseDown:
  441.                 
  442.                     myWindowPart = FindWindow(myEvent.where, &myWindow);
  443.  
  444.                     // window-related events:            
  445.                     switch (myWindowPart) {
  446.                         case inMenuBar:
  447.                             HandleMenuCommand(MenuSelect(myEvent.where));
  448.                             break;
  449.                             
  450.                         case inDrag: {
  451.                             Rect                 myRect;
  452.                             Movie                myMovie = NULL;
  453.                             MovieController     myMC = NULL;
  454.                             WindowObject         myWindowObject = NULL;
  455.                             
  456.                             myWindowObject = (WindowObject)GetWRefCon(myWindow);
  457.                             myMC = (**myWindowObject).fController;
  458.                             if (!(IsWindowObjectOurs(myWindowObject)) && (myMC == NULL))
  459.                                 break;
  460.                                 
  461.                             myMovie = MCGetMovie(myMC);
  462.                             
  463.                             GetMovieBox(myMovie, &myRect);
  464.                             myScreenRect = (**GetGrayRgn()).rgnBBox;
  465.                             DragAlignedWindow(myWindow, myEvent.where, &myScreenRect, &myRect, NULL);
  466.                         }
  467.                             break;
  468.                             
  469.                         case inContent:
  470.                             SelectWindow(myWindow);
  471.                             HandleContentClick(myWindow, &myEvent);
  472.                             break;
  473.                         
  474.                         case inGoAway:
  475.                             // if the window is closed, dispose the movie, the controller and the window
  476.                             if (TrackGoAway(myWindow, myEvent.where))
  477.                                 DoDestroyMovieWindow(myWindow);
  478.                             break;
  479.                     } // end switch(myWindowPart)
  480.                     break;
  481.  
  482.                 // system-level events:
  483.                 case updateEvt:
  484.                     myWindow = (WindowRef)myEvent.message;
  485.                     myRefreshArea = ((**(myWindow->visRgn)).rgnBBox);
  486.                     DoUpdateWindow(myWindow, &myRefreshArea);
  487.                     break;
  488.                     
  489.                 case keyDown:
  490.                 case autoKey:
  491.                     HandleKeyPress(&myEvent);
  492.                     break;
  493.                 
  494.                 case diskEvt:
  495.                     if (HiWord(myEvent.message) != noErr)
  496.                         (void)DIBadMount(myPoint, myEvent.message);
  497.                     break;
  498.                 
  499.                 case activateEvt:
  500.                     myWindow = (WindowRef)myEvent.message;
  501.                     
  502.                      if (IsAppWindow(myWindow)) {
  503.                         DoActivateWindow(myWindow, ((myEvent.modifiers & activeFlag) != 0 ));
  504.                     }
  505.                     break;
  506.                     
  507.                 case osEvt:
  508.                     switch ((myEvent.message > 24) & 0x00FF) {        // get high byte of word
  509.                         case suspendResumeMessage:
  510.                         
  511.                             // set the foreground/background state
  512.                             if ((myEvent.message & resumeFlag) != 0)
  513.                                 gAppInForeground = true;
  514.                             else
  515.                                 gAppInForeground = false;
  516.                             
  517.                             // activate the front window, if there is one    
  518.                             if (FrontWindow()) {
  519.                                 DoActivateWindow(FrontWindow(), !((myEvent.message & resumeFlag) == 0));
  520.                             }
  521.                             break;
  522.                         
  523.                         case mouseMovedMessage:
  524.                             break;
  525.                     }
  526.                     break;
  527.                 
  528.                 case kHighLevelEvent:
  529.                     AEProcessAppleEvent(&myEvent);
  530.                     break;
  531.                     
  532.                 case nullEvent:
  533.                     // do idle-time processing for all open windows in our window list
  534.                     myWindow = FrontWindow();
  535.                     while (myWindow != NULL) {
  536.                         if (gAppInForeground)
  537.                             DoIdle(myWindow);
  538.                         myWindow = (WindowPtr)(((WindowRecord*)myWindow)->nextWindow);
  539.                     }
  540.                     break;
  541.                     
  542.             } //switch (myEvent.what)
  543.         } //if (!isMovieEvent)
  544.     } //while (!gQuitFlag)
  545. }
  546.  
  547.  
  548. //////////
  549. //
  550. // IsAppWindow
  551. // Does the specified window belong to our application?
  552. //
  553. //////////
  554.  
  555. Boolean IsAppWindow (WindowRef theWindow)
  556. {
  557.     short            myWindowKind;
  558.     
  559.     if (theWindow == NULL)
  560.         return(false);
  561.     else {
  562.         myWindowKind = ((WindowPeek)theWindow)->windowKind;
  563.         return((myWindowKind >= userKind) || (myWindowKind == dialogKind));
  564.     }
  565. }
  566.  
  567.  
  568. //////////
  569. //
  570. // CreateWindowObject
  571. // Create a window object for the specified window.
  572. //
  573. //////////
  574.  
  575. WindowObject CreateWindowObject (WindowRef theWindow)
  576. {
  577.     WindowObject    myWindowObject = NULL;
  578.     
  579.     myWindowObject = (WindowObject)NewHandleClear(sizeof(WindowObjectRecord));
  580.     
  581.     if (myWindowObject != NULL) {
  582.         (**myWindowObject).fWindow = theWindow;
  583.         (**myWindowObject).fController = NULL;
  584.         (**myWindowObject).fObjectType = kMovieControllerObject;
  585.         (**myWindowObject).fAppData = NULL;
  586.         SetWRefCon(theWindow, (long)myWindowObject);        // store a ref to the record in the window
  587.     }
  588.     
  589.     return(myWindowObject);
  590. }
  591.  
  592.  
  593. //////////
  594. //
  595. // HandleKeyPress
  596. // Handle key presses.
  597. //
  598. //////////
  599.  
  600. void HandleKeyPress (EventRecord *theEvent)
  601. {
  602.     char        myKey;
  603.     
  604.     myKey = theEvent->message & charCodeMask;
  605.     
  606.     if (theEvent->modifiers & cmdKey) {
  607.         // if the command key is down, it must be a keyboard shortcut for a menu selection
  608.         HandleMenuCommand(MenuKey(myKey));
  609.     } else {
  610.         // otherwise, we'll assume it's meant for our application
  611.         HandleQTVRKeyPress(theEvent);
  612.     }
  613. }
  614.  
  615.  
  616. //////////
  617. //
  618. // ShowAboutDialogBox
  619. // Display the About box.
  620. //
  621. //////////
  622.  
  623. void ShowAboutDialogBox (void)
  624. {
  625.     DialogPtr        myDialog;
  626.     short             myItem;
  627.     //FontInfo        myFontInfo;
  628.     GrafPtr            mySavedPort;
  629.     
  630.     GetPort(&mySavedPort);
  631.     myDialog = GetNewDialog(kAboutBox, NULL, (WindowPtr) -1L); DebugAssert(myDialog != NULL);
  632.     SetPort(myDialog);
  633.  
  634.     // change font to Geneva, 9pt, bold, just for the sake of it...
  635.     //TextFont(applFont); TextSize(9); TextFace(bold);
  636.     //GetFontInfo(&myFontInfo);
  637.     
  638.     //(*((DialogPeek)myDialog)->textH)->txFont = applFont;
  639.     //(*((DialogPeek)myDialog)->textH)->txSize = 9;
  640.     //(*((DialogPeek)myDialog)->textH)->lineHeight = myFontInfo.ascent + myFontInfo.descent + myFontInfo.leading;
  641.     //(*((DialogPeek)myDialog)->textH)->fontAscent = myFontInfo.ascent;
  642.  
  643.     SetDialogDefaultItem(myDialog, 1);
  644.         
  645.     do {
  646.         ModalDialog(NULL, &myItem);
  647.     } while (myItem != ok);
  648.     
  649.     SetPort(mySavedPort);
  650.     DisposeDialog(myDialog);  DebugAssert(MemError() == noErr);
  651. }
  652.  
  653.  
  654. //////////
  655. //
  656. // ShowWarning
  657. // Display a warning box.
  658. //
  659. //////////
  660.  
  661. void ShowWarning (Str255 theMessage, OSErr theErr)
  662. {
  663.     Str255                myErrString;
  664.     
  665.     NumToString(theErr, myErrString);
  666.     ParamText("\pWarning!", theMessage, theErr ? myErrString:  NULL, NULL);
  667.     Alert(kAlertError, NULL);
  668. }
  669.  
  670.  
  671. // movie-related functions
  672.  
  673. //////////
  674. //
  675. // GetMCFromFrontWindow
  676. // Get the movie controller associated with the front window.
  677. //
  678. //////////
  679.  
  680. MovieController GetMCFromFrontWindow (void)
  681. {
  682.     MovieController     myMC = NULL;
  683.     WindowRef             myWindow = NULL;
  684.     WindowObject        myWindowObject = NULL;
  685.  
  686.     myWindow = FrontWindow();
  687.     if (myWindow == NULL)
  688.         return(NULL);
  689.  
  690.     if (!IsAppWindow(myWindow))
  691.         return(NULL);
  692.             
  693.     myWindowObject = (WindowObject)GetWRefCon(myWindow);
  694.     if (myWindowObject == NULL)
  695.         return(NULL);
  696.         
  697.     HLockHi((Handle)myWindowObject);
  698.  
  699.     // make sure this is a window object
  700.     if (!IsWindowObjectOurs(myWindowObject))
  701.         return(NULL);
  702.         
  703.     myMC = (**myWindowObject).fController;
  704.     HUnlock((Handle)myWindowObject);
  705.     
  706.     return(myMC);
  707. }
  708.  
  709.  
  710. //////////
  711. //
  712. // GetAppDataFromFrontWindow
  713. // Get the application-specific data associated with the front window.
  714. //
  715. //////////
  716.  
  717. Handle GetAppDataFromFrontWindow (void)
  718. {
  719.     return(GetAppDataFromWindow(FrontWindow()));
  720. }
  721.  
  722.  
  723. //////////
  724. //
  725. // GetAppDataFromWindow
  726. // Get the application-specific data associated with the specified window.
  727. //
  728. //////////
  729.  
  730. Handle GetAppDataFromWindow (WindowRef theWindow)
  731. {
  732.     WindowObject        myWindowObject = NULL;
  733.     
  734.     if (theWindow == NULL)
  735.         return(NULL);
  736.  
  737.     if (!IsAppWindow(theWindow))
  738.         return(NULL);
  739.             
  740.     myWindowObject = (WindowObject)GetWRefCon(theWindow);
  741.     if (myWindowObject == NULL)
  742.         return(NULL);
  743.     else
  744.         return(GetAppDataFromWindowObject(myWindowObject));
  745. }
  746.  
  747.  
  748. //////////
  749. //
  750. // GetAppDataFromWindowObject
  751. // Get the application-specific data associated with the specific window object.
  752. //
  753. //////////
  754.  
  755. Handle GetAppDataFromWindowObject (WindowObject theWindowObject)
  756. {
  757.     Handle                myAppData = NULL;
  758.             
  759.     if (theWindowObject == NULL)
  760.         return(myAppData);
  761.  
  762.     // make sure this is a window object belonging to our application
  763.     if (!IsWindowObjectOurs(theWindowObject))
  764.         return(myAppData);
  765.     
  766.     // get the app data handle from the window object
  767.     myAppData = (**theWindowObject).fAppData;
  768.     
  769.     return(myAppData);
  770. }
  771.  
  772.  
  773. //////////
  774. //
  775. // IsWindowObjectOurs
  776. // Does the specified window object belong to our application?
  777. //
  778. //////////
  779.  
  780. Boolean IsWindowObjectOurs (WindowObject theObject)
  781. {
  782.     OSType        myType = NULL;
  783.     
  784.     myType = (**theObject).fObjectType;
  785.     if (myType == kMovieControllerObject)
  786.         return(true);
  787.     else
  788.         return(false);
  789. }
  790.  
  791.  
  792. //////////
  793. //
  794. // DoCreateNewMovie
  795. // Create a new movie; returns true if successful.
  796. //
  797. //////////
  798.  
  799. Boolean DoCreateNewMovie (void)
  800. {
  801.     Movie                myMovie = NULL;
  802.     
  803.     myMovie = NewMovie(newMovieActive); DebugAssert(myMovie != NULL);
  804.     if (myMovie == NULL)
  805.         return(false);
  806.     
  807.     if (!DoCreateMovieWindow(myMovie))
  808.         return(false);
  809.     else    
  810.         return(true);
  811. }
  812.  
  813.  
  814. //////////
  815. //
  816. // DoCreateMovieWindow
  817. // Create a new movie window; returns true if successful.
  818. //
  819. //////////
  820.  
  821. Boolean DoCreateMovieWindow (Movie theMovie)
  822. {
  823.     Rect                 myRect = gDefaultWinRect;
  824.     WindowRef            myWindow = NULL;
  825.     MovieController        myMC = NULL;
  826.     WindowObject        myWindowObject = NULL;
  827.     GrafPtr                mySavedPort;
  828.     short                myRefNum;
  829.     short                myResID;
  830.     FSSpec                myFileFSSpec;
  831.         
  832.     myFileFSSpec.vRefNum = 0;
  833.  
  834.     GetPort(&mySavedPort);
  835.     myWindow = CreateMovieWindow(&myRect, gWindowTitle);
  836.     SetPort((GrafPtr) myWindow);
  837.     
  838.     if (myWindow == NULL)
  839.         return(false);
  840.     
  841.     myWindowObject = CreateWindowObject(myWindow);
  842.     if (myWindowObject == NULL)
  843.         return(false);
  844.     
  845.     // if we don't get a movie, call the internal QTUGetMovie that will get us one.
  846.     if (theMovie == NULL) {
  847.         theMovie = QTUGetMovie(&myFileFSSpec, &myRefNum, &myResID);
  848.         if (theMovie == NULL) {                          // user selected cancel or otherwise something bad happened.
  849.             DisposeWindow(myWindow);    // RTM: added these two lines, to prevent crashing when cancel selected
  850.             SetPort(mySavedPort);        // RTM
  851.             return(false);
  852.         }
  853.         
  854.         // add the FSSpec, refnum and resid values to the window object (we need these when we save the movie).
  855.         (**myWindowObject).fFileFSSpec = myFileFSSpec;
  856.         (**myWindowObject).fFileRefNum = myRefNum;
  857.         (**myWindowObject).fFileResID = myResID;
  858.         (**myWindowObject).fMovie = theMovie;
  859.         
  860.         // get movie title and set this to the window title.
  861.         SetWTitle(myWindow, myFileFSSpec.name);
  862.     }
  863.     
  864.     SetMovieGWorld(theMovie, (CGrafPtr)myWindow, 0);    // make sure the movie uses the window GWorld in all situations
  865.     myMC = SetupMovieWindowWithController(theMovie, myWindow);
  866.     
  867.     // do any application-specific window object initialization
  868.     InitApplicationWindowObject(myWindowObject);
  869.     
  870.     ShowWindow(myWindow);
  871.     SelectWindow(myWindow);                                // make it front-most, since it's just been created
  872.     InvalRect(&((GrafPtr)myWindow)->portRect);
  873.     
  874.     MCEnableEditing(myMC, true);                        // enable the default movie controller editing
  875.  
  876.     SetPort(mySavedPort);
  877.     return(true);
  878. }
  879.  
  880.  
  881. //////////
  882. //
  883. // SetupMovieWindowWithController
  884. // Configure the movie controller.
  885. //
  886. //////////
  887.  
  888. MovieController SetupMovieWindowWithController (Movie theMovie, WindowRef theWindow)
  889. {
  890.     MovieController            myMC;
  891.     Rect                    myRect;
  892.     GrafPtr                    mySavedPort;
  893.     WindowObject            myWindowObject;
  894.     short                    myMovieWidth;
  895.     short                    myMovieHeight;
  896.     
  897.     DebugAssert(theMovie != NULL); 
  898.     DebugAssert(theWindow != NULL);
  899.     
  900.     myWindowObject = (WindowObject)GetWRefCon(theWindow);        // get our window specific data
  901.     if (!IsWindowObjectOurs(myWindowObject))
  902.         return(NULL);                                            // quick sanity test of the window created
  903.     GetPort(&mySavedPort);
  904.     SetPort((GrafPtr)theWindow);
  905.     
  906.     // resize the movie bounding rect
  907.     GetMovieBox(theMovie, &myRect);
  908.     SetMovieBox(theMovie, &myRect);
  909.  
  910.     // create the movie controller.
  911.     myMC = NewMovieController(theMovie, &myRect, gMCFlags);
  912.     if (myMC == NULL)
  913.         return(NULL);
  914.     MCGetControllerBoundsRect(myMC, &myRect);
  915.     
  916.     // add grow box for the movie controller and also an action filter that resizes the controllers
  917.     MCDoAction(myMC, mcActionSetGrowBoxBounds, &gLimitRect);
  918.     
  919.     // install an action filter that resizes the controllers
  920.     // and does any application-specific mc action processing
  921.     MCSetActionFilterWithRefCon(myMC, NewMCActionFilterWithRefConProc(ApplicationMCActionFilterProc), (long)theWindow);
  922.                                                     
  923.     // see if the bounding rects are sane
  924.     myMovieWidth = myRect.right - myRect.left;
  925.     myMovieHeight = myRect.bottom - myRect.top;
  926.     
  927.     myRect.top = myRect.left  = 0;
  928.     myRect.right = myMovieWidth;
  929.     myRect.bottom = myMovieHeight;
  930.     
  931.     // resize the window
  932.     SizeWindow(theWindow, myMovieWidth, myMovieHeight, true);
  933.     MoveWindow(theWindow, kDefaultX, kDefaultY, false);                                
  934.  
  935.     SetPort(mySavedPort);
  936.  
  937.     // add any additional controller functionality
  938.     AddControllerFunctionality(myMC);
  939.  
  940.     // save important stuff into the window object
  941.     {    
  942.         Rect        myRect;
  943.         OSErr        myErr;
  944.  
  945.         (**myWindowObject).fController = myMC;
  946.         myErr = MCGetControllerBoundsRect(myMC, &myRect); DebugAssert(myErr == noErr);
  947.         (**myWindowObject).fOriginalSize = myRect;
  948.     }
  949.     
  950.     return(myMC);
  951. }
  952.  
  953.  
  954. //////////
  955. //
  956. // DoUpdateMovieFile
  957. // Update the file (if any) attached to the movie.
  958. //
  959. //////////
  960.  
  961. Boolean DoUpdateMovieFile (WindowRef theWindow)
  962. {
  963.     Movie                     myMovie = NULL;
  964.     WindowObject            myWindowObject = NULL;
  965.     MovieController            myMC = NULL;
  966.     OSErr                    myErr;
  967.     
  968.     if ((theWindow == NULL) || !IsAppWindow(theWindow))
  969.         return(false);
  970.         
  971.     myWindowObject = (WindowObject)GetWRefCon(theWindow); DebugAssert(myWindowObject != NULL);
  972.     myMC = (**myWindowObject).fController; DebugAssert(myMC != NULL);
  973.     
  974.     if (!(IsWindowObjectOurs(myWindowObject)) && (myMC == NULL))
  975.         return(false);
  976.     
  977.     myMovie = MCGetMovie(myMC); DebugAssert(myMovie != NULL);
  978.     if (myMovie == NULL)
  979.         return(false);
  980.         
  981.     if ( (**myWindowObject).fFileRefNum == -1) {            // brand new movie, so no file attached to it.
  982.         if (QTUSaveMovie(myMovie) != noErr)
  983.             return(false);    
  984.     } else {                                            // we have an existing file; just update the movie resource
  985.         // open the movie resource file, update the resource, and then close it again!
  986.         myErr = OpenMovieFile(& (**myWindowObject).fFileFSSpec, & (**myWindowObject).fFileRefNum, fsRdWrPerm);
  987.         DebugAssert(myErr == noErr);
  988.         if (myErr != noErr)
  989.             return(false);
  990.         
  991.         myErr = UpdateMovieResource(myMovie, (**myWindowObject).fFileRefNum, (**myWindowObject).fFileResID, NULL);
  992.         DebugAssert(myErr == noErr);
  993.         
  994.         CloseMovieFile((**myWindowObject).fFileRefNum);
  995.     }
  996.     
  997.     if (myErr == noErr)
  998.         return(true);
  999.     else
  1000.         return(false);
  1001. }
  1002.  
  1003.  
  1004. //////////
  1005. //
  1006. // DoDestroyMovieWindow
  1007. // Close the specified movie window.
  1008. //
  1009. //////////
  1010.  
  1011. void DoDestroyMovieWindow (WindowRef theWindow)
  1012. {
  1013.     Movie                     myMovie;
  1014.     MovieController            myMC;
  1015.     WindowObject            myWindowObject;
  1016.     
  1017.     DebugAssert(theWindow != NULL);
  1018.     
  1019.     if (theWindow == NULL)
  1020.         return;
  1021.     
  1022.     myWindowObject =(WindowObject)GetWRefCon(theWindow);
  1023.     MoveHHi((Handle)myWindowObject);
  1024.     HLock((Handle)myWindowObject);
  1025.     
  1026.     if (IsWindowObjectOurs(myWindowObject)) {
  1027.     
  1028.         // do any application-specific window clean-up
  1029.         RemoveApplicationWindowObject(myWindowObject);
  1030.         
  1031.         myMC = (**myWindowObject).fController;
  1032.         myMovie = MCGetMovie(myMC);
  1033.         
  1034.         if (myMovie != NULL)
  1035.             DisposeMovie(myMovie); DebugAssert(MemError() == noErr);
  1036.     
  1037.         if (myMC != NULL)
  1038.             DisposeMovieController(myMC); DebugAssert(MemError() == noErr);
  1039.     
  1040.         if ((**myWindowObject).fFileRefNum != -1)
  1041.             CloseMovieFile((**myWindowObject).fFileRefNum);
  1042.         
  1043.         (**myWindowObject).fObjectType = NULL;
  1044.         (**myWindowObject).fController = NULL;
  1045.         (**myWindowObject).fFileResID = NULL;
  1046.         (**myWindowObject).fFileRefNum = NULL;
  1047.         
  1048.         DisposeHandle((Handle)myWindowObject); DebugAssert(MemError() == noErr);
  1049.         DisposeWindow(theWindow); DebugAssert(MemError() == noErr);
  1050.         
  1051.         CompactMem(0xFFFFFFFF);        // we might as well compact the mem here for getting better performance later.
  1052.     }
  1053. }
  1054.  
  1055.  
  1056. //////////
  1057. //
  1058. // DoActivateWindow
  1059. // Activate the specified window.
  1060. //
  1061. //////////
  1062.  
  1063. void DoActivateWindow (WindowRef theWindow, Boolean isBecomingActive)
  1064. {
  1065.     WindowObject         myWindowObject = NULL;
  1066.     MovieController        myMC = NULL;
  1067.     GrafPtr                mySavedPort = NULL;
  1068.     
  1069.     GetPort(&mySavedPort);
  1070.     SetPort((GrafPtr)theWindow);
  1071.     
  1072.     myWindowObject = (WindowObject)GetWRefCon(theWindow);
  1073.     if (myWindowObject != NULL) {
  1074.         myMC = (**myWindowObject).fController;
  1075.         if ((IsWindowObjectOurs(myWindowObject)) && (myMC != NULL)) {
  1076.             MCActivate(myMC, theWindow, isBecomingActive);
  1077.         }
  1078.     }
  1079.     
  1080.     SetPort(mySavedPort);
  1081. }
  1082.  
  1083.  
  1084.  
  1085.